﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using F1010DB.CustomEntity.Master;
using F1010DB.CustomEntity.InitDanhMuc;
using F1010DB.Enums;
using System.Data;
using F1010DB.Constant;
namespace F1010DB.Common
{
    /// <summary>
    /// Lớp này dùng để xử lý các custom common bảng giá trị
    /// </summary>
    public abstract class AbstractClassForCommonMaster : AbstractGetBridgeConnect
    {
        private const char DATE_SPLIT_1 = '-';
        private const char DATE_SPLIT_2 = '/';

        private string commonId = null;

        private MasterCustomCommon masterCustom = null;

        private DataTable dt = null;

        // Tạo thực thể entity
        private List<MasterCustomCommon> masterCustomCommon1 = null;

        private RuleBoolean rule = new RuleBoolean();

        public RuleBoolean ruleInputCondition { set; get; }

        protected abstract string setCommonId();


        
        /// <summary>
        /// filter common
        /// </summary>
        /// <param name="rule"></param>
        /// <returns></returns>
        private MasterCustomCommon filterCommon(RuleBoolean rule)
        {
            //init();
            commonId = setCommonId();
            if (InitDisplayLoad.commonMaster == null)
            {
                return null;
            }

            var qu = from p in InitDisplayLoad.commonMaster
                     where p.Key1.Equals(rule.key1) && p.Key2.Equals(rule.key2) && p.Key3.Equals(rule.key3)
                         && p.Key4.Equals(rule.key4) && p.Key5.Equals(rule.key5) && p.CommId.Equals(commonId)
                     select p;


            return qu.ToList<MasterCustomCommon>().First();

        }


        

        /// <summary>
        /// Xử lý tính toán logical với chuỗi và ngày
        /// </summary>
        /// <param name="t"></param>
        /// <param name="l"></param>
        /// <returns></returns>
        public bool isBussinessLogical(EnumForMaster.TypeMaster t, EnumForMaster.Logic l)
        {
            rule.commonMaster = filterCommon(ruleInputCondition);
            rule.currentValue = ruleInputCondition.currentValue;

            if (t == EnumForMaster.TypeMaster.STRING)
            {
                return logicalForString(rule.currentValue, rule.commonMaster.Value1, l);
            } 
            else if (t == EnumForMaster.TypeMaster.DATETIME)
            {
                return logicalForDateTime(rule.currentValue, rule.commonMaster.Value1, l);
            }

            return false;
        }

        /// <summary>
        /// Xử lý kết hợp tính toán với các dạng số
        /// </summary>
        /// <param name="t"></param>
        /// <param name="l"></param>
        /// <param name="c"></param>
        /// <returns></returns>
        public int bussinesssForCalc(EnumForMaster.TypeMaster t, EnumForMaster.Logic l, EnumForMaster.Calc c)
        {
            int ret = -1;

            if (t == EnumForMaster.TypeMaster.INTERGER || t == EnumForMaster.TypeMaster.DECIMAL )
            {
                decimal decCurValue = 0;
                decimal decValue = 0;

                int iValue = 0;
                int iCurValue = 0;
                bool isTruth = false;

                rule.commonMaster = filterCommon(ruleInputCondition);
                rule.currentValue = ruleInputCondition.currentValue;

                // Kiểm tra định dạng
                switch(t)
                {
                    // Kiểm tra 1 trong hai kiểu (Interger hay decimal)
                    case EnumForMaster.TypeMaster.INTERGER:
                        // Lấy giá trị kiểm chứng
                        iValue = Int16.Parse(rule.commonMaster.Value1);
                        //Lấy giá trị nhập liệu
                        iCurValue = Int16.Parse(rule.currentValue);
                        isTruth = logicalForInterger(iCurValue, iValue, Int16.Parse(rule.commonMaster.valueCalc), c, l);
                        break;
                    case EnumForMaster.TypeMaster.DECIMAL:
                        decCurValue = Decimal.Parse(rule.currentValue);
                        decValue = Decimal.Parse(rule.commonMaster.Value1);
                        isTruth = logicalForDecimal(decCurValue, decValue, Decimal.Parse(rule.commonMaster.valueCalc), c, l);
                        break;
                }

                if (isTruth)
                {
                    ret = 1;
                }
                else
                {
                    ret = 0;
                }
            }  

            return ret;
        }
        
        private bool logicalForInterger(int value1, int value2, int valueCalc, EnumForMaster.Calc e, EnumForMaster.Logic l)
        {
            int result = 0;

            switch (e)
            {
                case EnumForMaster.Calc.ADD:
                    result = value2 + valueCalc;
                    break;
                case EnumForMaster.Calc.DEVIDE:
                    result = value2 / valueCalc;
                    break;
                case EnumForMaster.Calc.MULTI:
                    result = value2 * valueCalc;
                    break;
                case EnumForMaster.Calc.SUBTRACT:
                    result = value2 - valueCalc;
                    break;
                default:
                    result = value2;
                    break;
            }

            bool isCompare = false;

            switch (l)
            {
                case EnumForMaster.Logic.EQUAL:
                    isCompare = value1 == result;
                    break;
                case EnumForMaster.Logic.GREATER_THAN:
                    isCompare = value1 > result;
                    break;
                case EnumForMaster.Logic.GREATER_AND_EQUAL:
                    isCompare = value1 >= result;
                    break;
                case EnumForMaster.Logic.LESS_THAN:
                    isCompare = value1 < result;
                    break;
                case EnumForMaster.Logic.DIFF:
                    isCompare = value1 != result;
                    break;
                default:
                    isCompare = true;
                    break;
            }

            return isCompare;
        }

        /// <summary>
        /// Xử lý tính toán trong kiểu thập phân
        /// </summary>
        /// <param name="value1">Giá trị nhập</param>
        /// <param name="value2">Giá trị quy định</param>
        /// <param name="valueCalc">Độ tăng giảm</param>
        /// <param name="e"></param>
        /// <param name="l"></param>
        /// <returns></returns>
        private bool logicalForDecimal(decimal value1, decimal value2, decimal valueCalc, EnumForMaster.Calc e, EnumForMaster.Logic l)
        {
            decimal result = 0;

            switch (e)
            {
               case EnumForMaster.Calc.ADD:
                    result = value2 + valueCalc;
                    break;
                case EnumForMaster.Calc.DEVIDE:

                    result = value2 / valueCalc;
                    break;
                case EnumForMaster.Calc.MULTI:
                    result = value2 * valueCalc;
                    break;
                case EnumForMaster.Calc.SUBTRACT:
                    result = value2 - valueCalc;
                    break;
                default:
                    result = value2;
                    break;
            }

            bool isCompare = false;

            switch (l)
            {
                case EnumForMaster.Logic.EQUAL:
                    isCompare = value1 == result;
                    break;
                case EnumForMaster.Logic.GREATER_THAN:
                    isCompare = value1 > result;
                    break;
                case EnumForMaster.Logic.GREATER_AND_EQUAL:
                    isCompare = value1 >= result;
                    break;
                case EnumForMaster.Logic.LESS_THAN:
                    isCompare = value1 < result;
                    break;
                case EnumForMaster.Logic.DIFF:
                    isCompare = value1 != result;
                    break;
                default:
                    isCompare = false;
                    break;
            }

            return isCompare;
        }

        /// <summary>
        /// Xử lý phép toán với kiểu chuổi
        /// </summary>
        /// <param name="s1">Chuỗi nhập</param>
        /// <param name="s2">Chuỗi định nghĩa</param>
        /// <param name="l"></param>
        /// <returns></returns>
        private bool logicalForString(string s1, string s2, EnumForMaster.Logic l)
        {
            switch (l)
            {
                case EnumForMaster.Logic.DIFF:
                    return !s1.Equals(s2);
                case EnumForMaster.Logic.EQUAL:
                    return s1.Equals(s2);
            }
            return false ;
        }

        /// <summary>
        /// Xử lý kiểu ngày tháng năm theo phép toán logic
        /// </summary>
        /// <param name="currentDate">Ngày nhập</param>
        /// <param name="valueDate">Ngày giá trị</param>
        /// <param name="l"></param>
        /// <returns></returns>
        private bool logicalForDateTime(string currentDate, string valueDate, EnumForMaster.Logic l)
        {
            int[] intCurDate = new int[3];
            int[] valCurDate = new int[3];
            string[] arr1 = new string[3];
            string[] arr2 = new string[3];
            
            //Chuyển các kiểu sang kiểu ngày tháng năm

            if (currentDate.Contains('-'))
            {
               arr1 = currentDate.Split(DATE_SPLIT_1);
            } else if(currentDate.Contains('/'))
            {
                arr1 = currentDate.Split(DATE_SPLIT_2);
            }

            // Chuyển những giá trị ngày tháng năm nhập sang dãy
            // Sau đó chuyển sang kiểu số
            for(int i = 0; i < 3; i++)
            {
                intCurDate[i] = Int16.Parse(arr1[i]);
            }

            //Xử lý định nghĩa ngày tháng
            // Giá trị định nghĩa
            if (valueDate.Contains('-'))
            {
                arr2 = valueDate.Split(DATE_SPLIT_1);
            } else if (valueDate.Contains('/'))
            {
                arr2 = valueDate.Split(DATE_SPLIT_2);
            }
            
            for (int i = 0; i < 3; i++)
            {
                valCurDate[i] = Int16.Parse(arr2[i]);
            }

            DateTime dtCurrentDate = new DateTime(intCurDate[2], intCurDate[1], intCurDate[0]);
            DateTime dtValueDate = new DateTime(valCurDate[2], valCurDate[1], valCurDate[0]);
            bool isCompare = false;

            switch(l)
            {
                case EnumForMaster.Logic.EQUAL:
                    isCompare = dtCurrentDate == dtValueDate;
                    break;
                case EnumForMaster.Logic.DIFF:
                    isCompare = dtCurrentDate != dtValueDate;
                    break;
                case EnumForMaster.Logic.GREATER_AND_EQUAL:
                    isCompare = dtCurrentDate >= dtValueDate;
                    break;
                case EnumForMaster.Logic.GREATER_THAN:
                    isCompare = dtCurrentDate > dtValueDate;
                    break;
                case EnumForMaster.Logic.LESS_AND_EQUAL:
                    isCompare = dtCurrentDate <= dtValueDate;
                    break;
                case EnumForMaster.Logic.LESS_THAN:
                    isCompare = dtCurrentDate < dtValueDate;
                    break;
                case EnumForMaster.Logic.NONE:
                    isCompare = false;
                    break;
            }
            return isCompare;
        }



    }
}
